import { AfterContentInit, Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { ThreadsCollectStatsAndReplyVo } from 'src/app/model/threads-collect-stats-and-reply-vo';
import { ThreadsService } from 'src/app/services/threads.service';
import { BtnNaviSharedService } from 'src/app/services/btn-navi-shared.service';
import { MemberStorageService } from 'src/app/services/member-storage.service';
import { MemberVo } from 'src/app/model/member-vo';
import { ThreadsStatsVo } from 'src/app/model/threads-stats-vo';
import { UtilService } from 'src/app/services/util.service';
import { HttpErrorResponse } from '@angular/common/http';
import { Title } from '@angular/platform-browser';
import { environment } from 'src/environments/environment';
import { ReportFormEmbedComponent } from 'src/app/embed/report-form-embed/report-form-embed.component';
import { ReplyService } from 'src/app/services/reply.service';
import { ThreadsVo } from 'src/app/model/threads-vo';
import { ReportEntityDataService, ReportReply } from 'src/app/services/report-entity-data.service';
import { Subscription } from 'rxjs';
import { QuickReplyFormComponent } from 'src/app/embed/quick-reply-form/quick-reply-form.component';
import { QuickReplyDataService } from 'src/app/services/quick-reply-data.service';
import { ReplyVo } from 'src/app/model/reply-vo';
import { ReplyInfiniteScrollListComponent } from 'src/app/posts/reply-infinite-scroll-list/reply-infinite-scroll-list.component';
import { concatMap, map } from 'rxjs/operators';
import { BoardService } from 'src/app/services/board.service';
import { BoardVo } from 'src/app/model/board-vo';
import { ThreadsFullGraph } from 'src/app/model/threads-full-graph';

@Component({
  selector: 'app-index',
  templateUrl: './index.component.html',
  styles: [``]
})
/**
 * 话题内容页
 * @constructor
 */
export class IndexComponent implements OnInit, AfterContentInit, OnDestroy {
  public item!: ThreadsFullGraph;
  public errorMessage: string = '';
  //是否仅查看楼主
  public filterMaster: number = 0;
  //回复的排序类型(0升序)(1降序)
  public sortCategory: number = 0;
  //当前页码
  public page: number = 1;
  //每页显示的数量
  public pageSize: number = 20;
  //是否可以点赞,true可以,false点过赞了
  public canLiked: boolean = true;
  //是否可以收藏,true可以,false收藏过了
  public canFavorited: boolean = true;
  //当前登录的会员
  private curMember: MemberVo | null;
  public online: boolean = false;
  public avatar: string | null = null;
  private token: string;
  private ip: string = '127.0.0.1';
  public scale: string = '640x360';
  //引用举报的子组件
  @ViewChild('reportF', { static: false })
  public reportFormCmp!: ReportFormEmbedComponent;
  //引用快速回复的子组件
  @ViewChild('quickReplyF', { static: false })
  public replyFormCmp!: QuickReplyFormComponent;
  @ViewChild('replyResult', { static: false })
  public replyResult!: ReplyInfiniteScrollListComponent;
  public reportSubscription!: Subscription;
  public replySubscription!: Subscription;

  constructor(
    private title: Title,
    private router: Router,
    private activatedRoute: ActivatedRoute,
    private threadsService: ThreadsService,
    private boardService: BoardService,
    private replyService: ReplyService,
    private memberStorage: MemberStorageService,
    private reportShare: ReportEntityDataService,
    private replyIdShare: QuickReplyDataService,
    private util: UtilService,
    private btnNaviSharedService: BtnNaviSharedService) {
    this.btnNaviSharedService.active(false); //不显示全局的导航
    this.curMember = this.memberStorage.get();
    this.token = this.util.randomAlphaNumeric(8) || '123456';
    this.memberStorage.getIpCliente().subscribe(ipAddr => this.ip = ipAddr);
    this.online = this.curMember !== null;
    this.avatar = this.curMember?.avatar ?? '';

  }

  ngAfterContentInit(): void {
    let topicConstr = this.activatedRoute.snapshot.paramMap.get('constr') ?? '-';
    let x: number[] = this.threadsService.parseConString(topicConstr);
    try {
      this.loadListener(x[0], this.curMember?.id ?? 0, this.curMember?.nickname ?? 'guest');
    } catch (e) {
    }
    
  }

  private loadListener(topicId: number, memberId: number, memberNickname: string): void {
    this.threadsService.browse(topicId, memberId, memberNickname, this.token, this.ip).subscribe({
      next: response => {
      },
      error: err => {
        let bsError = '';
        if (err instanceof HttpErrorResponse) {
          if (err.error instanceof ErrorEvent) {
            bsError = err.error.message;
          } else {
            bsError = (err.status == 417) ? '浏览失败' : err.error;
          }
        } else if (err instanceof Error) {
          bsError = err.message;
        } else { bsError = err; }
        console.log('[Threads-CTL]browse error ' + bsError);
      },
      complete: () => {
        console.log('[Threads-CTL]browse Completed');
      }
    });
  }

  ngOnInit(): void {
    let topicConstr = this.activatedRoute.snapshot.paramMap.get('constr') ?? '-';
    this.filterMaster = parseInt(this.activatedRoute.snapshot.queryParamMap.get('author') ?? '0');
    this.sortCategory = parseInt(this.activatedRoute.snapshot.queryParamMap.get('sort') ?? '0');
    this.page = +(this.activatedRoute.snapshot.queryParamMap.get('p') ?? 1);
    this.pageSize = +(this.activatedRoute.snapshot.queryParamMap.get('s') ?? environment.pageSize);
    //当左侧操作数为 null 或 undefined 时，其返回右侧的操作数，否则返回左侧的操作数。
    let x: number[] = this.threadsService.parseConString(topicConstr);
    //取消ThreadsHeaderEmbedComponent组件
    this.threadsService.getContent(x[0], this.scale).pipe(
      concatMap(
        (tscr: ThreadsCollectStatsAndReplyVo) => this.boardService.get(x[1]).pipe(
          map(
            (board: BoardVo) => {
              return { threadsVo: tscr.threadsVo, statsVo: tscr.statsVo, replyVo: tscr.replyVo, memberVo: tscr.memberVo, boardVo: board } as ThreadsFullGraph;
            })
        ))).subscribe({
          next: response => {
            this.item = response;
            this.title.setTitle(this.item.threadsVo.title);
          },
          error: err => {
            if (err instanceof HttpErrorResponse) {
              if (err.error instanceof ErrorEvent) {
                this.errorMessage = err.error.message;
              } else {
                if (err.status === 404) {
                  //跳转
                  this.router.navigate(['404']);
                } else {
                  this.errorMessage = err.error;
                }
              }
            } else if (err instanceof Error) {
              this.errorMessage = err.message;
            } else { this.errorMessage = err; }
          },
          complete: () => { console.log('[Threads-CTL]Completed'); this.unionCheckThreads(this.curMember?.id ?? 0, x[0]);}
        });
    //订阅MemberItemEmbedComponent发布出来的
    this.reportSubscription = this.reportShare.query().subscribe((rr: ReportReply) => this.toggleChildReplyDrawer(rr));
    //订阅ReplyItemMoodEmbedComponent发布出来的
    this.replySubscription = this.replyIdShare.query().subscribe(replyId => this.toggleQuickReplyDrawer(replyId));
  }

  //退订MemberItemEmbedComponent相关Subject
  public ngOnDestroy(): void {
    if (this.reportSubscription) {
      this.reportSubscription.unsubscribe();
    }
    if (this.replySubscription) {
      this.replySubscription.unsubscribe();
    }
  }

  /**
   * 是否已经点过赞了
   * @deprecated
   */
  private isLiked(): void {
    if (this.curMember !== null && this.item && this.item.threadsVo) {
      this.threadsService.isLiked(this.item.threadsVo.id, this.curMember.id).subscribe({
        next: response => {
        },
        error: err => {
          if (err instanceof HttpErrorResponse && err.status === 417) {
            this.canLiked = false;
          }
        },
        complete: () => {
          console.log('[Threads-CTL]Like check Completed');
        }
      });
    }
  }

  /**
   * 是否已经收藏过了
   * @deprecated
   */
  private isFavorited(): void {
    if (this.curMember !== null && this.item && this.item.threadsVo) {
      this.threadsService.isFavorited(this.item.threadsVo.id, this.curMember.id).subscribe({
        next: response => {
        },
        error: err => {
          if (err instanceof HttpErrorResponse && err.status === 417) {
            this.canFavorited = false;
          }
        },
        complete: () => {
          console.log('[Threads-CTL]Favorite check Completed');
        }
      });
    }
  }
  
  /**
   * 联合点赞,收藏检查
   * @param memberId 
   * @param topicId 
   */
  private unionCheckThreads(memberId: number, topicId: number): void {
    if (memberId > 0 && topicId > 0) {
      this.threadsService.getSSEUnionCheckResult(topicId, memberId).subscribe(res => {
        if (res.id === topicId) {
          this.canLiked = parseInt(res.like) > 0 ? true : false;
          this.canFavorited = parseInt(res.favorite) > 0 ? true : false;
        }
      });
    }
  }

  //话题点赞
  public likeThreads(event: Event): void {
    if (this.curMember === null) {
      this.util.alertError('暂不支持游客进行话题点赞');
    }
    if (this.item && this.item.statsVo) {
      let curTs: ThreadsStatsVo = this.item.statsVo;
      //REST API
      this.threadsService.like(curTs.threads, this.curMember?.id ?? 0, this.curMember?.nickname ?? 'guest', this.token, this.ip).subscribe({
        next: response => {
          curTs.likes += 1;
          this.canLiked = false;
        },
        error: err => {
          let em: string = '';
          if (err instanceof HttpErrorResponse) {
            if (err.error instanceof ErrorEvent) {
              em = err.error.message;
            } else {
              em = (err.status === 417) ? '操作失败' : err.error;
            }
          } else if (err instanceof Error) {
            em = err.message;
          } else { em = err; }
          this.util.alertError(em);
          console.log('[Threads-CTL]like error ' + em);
        },
        complete: () => { console.log('[Threads-CTL]like Completed'); }
      });
    }
  }

  //收藏话题
  public favoriteThreads(event: Event): void {
    if (this.curMember === null) {
      this.util.alertError('暂不支持游客收藏话题');
    }
    if (this.item && this.item.statsVo) {
      let curTs: ThreadsStatsVo = this.item.statsVo;
      //REST API
      this.threadsService.favorite(curTs.threads, this.curMember?.id ?? 0, this.curMember?.nickname ?? 'guest', this.token, this.ip).subscribe({
        next: response => {
          curTs.favorites += 1;
          this.canFavorited = false;
        },
        error: err => {
          let em: string = '';
          if (err instanceof HttpErrorResponse) {
            if (err.error instanceof ErrorEvent) {
              em = err.error.message;
            } else {
              em = (err.status == 417) ? '操作失败' : err.error;
            }
          } else if (err instanceof Error) {
            em = err.message;
          } else { em = err; }
          this.util.alertError(em);
          console.log('[Threads-CTL]favorite error ' + em);
        },
        complete: () => { console.log('[Threads-CTL]favorite Completed'); }
      });
    }
  }

  //举报回复
  private reportReply(reportData: any): void {
    if (this.curMember === null) {
      this.util.alertError('暂不支持游客举报回复');
      return;
    }
    if (this.item && this.item.threadsVo) {
      let curT: ThreadsVo = this.item.threadsVo;
      this.replyService.report(reportData.reply, curT.id, reportData.reason, reportData.type, this.curMember?.id ?? 0, this.curMember?.nickname ?? 'guest', reportData.token, this.ip).subscribe({
        next: response => {
          this.util.alertSuccess("回复举报成功");
        },
        error: err => {
          let em: string = '';
          if (err instanceof HttpErrorResponse) {
            if (err.error instanceof ErrorEvent) {
              em = err.error.message;
            } else {
              em = (err.status == 404) ? '举报失败' : err.error;
            }
          } else if (err instanceof Error) {
            em = err.message;
          } else { em = err; }
          this.util.alertError(em);
          console.log('[Threads-CTL]report posts error ' + em);
        },
        complete: () => {
          console.log('[Threads-CTL]report posts Completed');
          this.reportFormCmp.close();
        }
      });
    }
    this.util.alertError('回复举报失败');
  }

  //举报话题
  private reportThreads(reportData: any): void {
    if (this.curMember === null) {
      this.util.alertError('暂不支持游客举报话题');
      return;
    }
    this.threadsService.report(reportData.threads, reportData.reason, reportData.type, this.curMember?.id ?? 0, this.curMember?.nickname ?? 'guest', reportData.token, this.ip).subscribe({
      next: response => {
        this.util.alertSuccess("话题举报成功");
      },
      error: err => {
        let em: string = '';
        if (err instanceof HttpErrorResponse) {
          if (err.error instanceof ErrorEvent) {
            em = err.error.message;
          } else {
            em = (err.status == 404) ? '举报失败' : err.error;
          }
        } else if (err instanceof Error) {
          em = err.message;
        } else { em = err; }
        this.util.alertError(em);
        console.log('[Threads-CTL]report topic error ' + em);
      },
      complete: () => {
        console.log('[Threads-CTL]report topic Completed');
        this.reportFormCmp.close();
      }
    });
  }

  //举报菜单的输出@Output
  public reportFormAction(reportFormData: any): void {
    if (reportFormData.reply > 0) {
      return this.reportReply(reportFormData);
    }
    if (reportFormData.threads > 0) {
      return this.reportThreads(reportFormData);
    }
  }

  //举报抽屉菜单开关的切换
  public toggleChildReplyDrawer(reportReply: ReportReply): void {
    if (reportReply.replyFloor == 1) {
      if (this.item && this.item.threadsVo) {
        let curT: ThreadsVo = this.item.threadsVo;
        //举报话题
        this.reportFormCmp.toggleThreadsDrawer(curT.id);
      } else {
        this.util.alertError('话题参数遗失');
      }
    } else {
      //举报回复
      this.reportFormCmp.toggleReplyDrawer(reportReply.replyId);
    }
  }

  //快速回复菜单的输出@Output
  public quickReplyFormAction(quickReplyFormData: any): void {
    if (this.curMember === null) {
      this.util.alertError('暂不支持游客回复');
      return;
    }
    if (this.item && this.item.threadsVo) {
      let curT: ThreadsVo = this.item.threadsVo;
      if (curT.status !== 4) {
        this.util.alertError('话题状态不满足回复条件');
        return;
      }
      this.replyService.reply(
        curT.volumes,
        curT.board,
        curT.id,
        quickReplyFormData.quote,
        quickReplyFormData.content,
        quickReplyFormData.scale,
        this.curMember?.id ?? 0,
        this.curMember?.nickname ?? 'guest',
        quickReplyFormData.token,
        this.ip).subscribe({
          next: response => {
            let curReply: ReplyVo = response;
            this.replySuccessCallFun(curReply);
          },
          error: err => {
            let em: string = '';
            if (err instanceof HttpErrorResponse) {
              if (err.error instanceof ErrorEvent) {
                em = err.error.message;
              } else {
                em = (err.status === 404) ? '回复操作失败' : err.error;
              }
            } else if (err instanceof Error) {
              em = err.message;
            } else { em = err; }
            this.util.alertError(em);
            console.log('[Threads-CTL]quick reply error ' + em);
          },
          complete: () => {
            console.log('[Threads-CTL]quick reply Completed');
            this.replyFormCmp.close();
          }
        });
    }
    this.util.alertError('回复失败');
  }

  //快速回复抽屉菜单的开关的切换
  public toggleQuickReplyDrawer(replyId: number): void {
    this.replyFormCmp.toggle(replyId);
  }

  //回复成功后的回调
  public replySuccessCallFun(reply: ReplyVo): void {
    //添加到当前回复的结果集中
    this.replyResult.items.push({ replyVo: reply, memberVo: this.curMember });
    this.util.alertSuccess("回复成功");
    //滚动到底部
    try {
      window.scrollTo(0, document.body.scrollHeight);
    } catch (err) { }
  }
}
